# -*- coding: UTF-8 -*-
# ！/usr/bin/env python3

import copy
import json
import urllib
from log_helper import logger
import module.globals as gbl
import requests
from env_constants.constants_public import REQUEST_METHOD
import allure
from common_seal import CommonUtils


class Requester(object):
    def __init__(self, param=None):
        #已默认，如有需要请传入
        self.cached_headers = {
            "Content-Type":'application/json',
            "X-ENV": 'AUTO_TEST'
        }
        self.param = param
    @staticmethod
    def _full_url(domain, path):
        """
        根据 path 返回完整 URL
        :param domain: 域名
        :param path: 相对路径
        :return: 完整 URL
        """
        if path.startswith('/'):
                new_path = path
        return urllib.parse.urljoin(domain, new_path)

    def get(self, url, domain, header=None, **kwargs):
        """

        :param url: 请求地址与参数都放在url里面，发送请求的时候发送纯url
        :param domain: 域名
        :param header:
        :param kwargs:  请求参数放这里,如:get(url='xxxx', domain=gbl.OMS_CART_URL, data = data)
        :return: class:`Response <Response>` object
        """
        response,headers = self.send_request(url, domain, REQUEST_METHOD['GET'], header, **kwargs)
        logger().debug(f"你的headers是：{headers}")
        resp, log_content = CommonUtils.format_response_for_log(response)
        logger().debug(f"你的出参是：{log_content}")
        allure.attach(log_content, name='响应内容', attachment_type=allure.attachment_type.JSON)
        return resp

    def post(self, url, domain, header=None, *args, **kwargs):
        """
        :param url: 请求地址
        :param domain: 域名
        :param header:
        :param args:
        :param kwargs: 请求参数放这里,如：post(url='xxxx', data=data, domain=gbl.OMS_CART_URL)
        :return: class:`Response <Response>` object\
        """

        response,headers = self.send_request(url, domain, REQUEST_METHOD['POST'], header, *args, **kwargs)
        logger().debug(f"你的headers是：{headers}")
        logger().debug(f"你的入参是：{kwargs}")
        resp, log_content = CommonUtils.format_response_for_log(response)
        logger().debug(f"你的出参是：{log_content}")
        allure.attach(log_content, name='响应内容', attachment_type=allure.attachment_type.JSON)
        return resp

    def delete(self, url, domain, **kwargs):
        return self.send_request(url, domain, REQUEST_METHOD['DELETE'], **kwargs)

    def put(self, url, domain, header=None, *args, **kwargs):
        """

        :param header:
        :param url:
        :param domain:
        :param kwargs:
        :return:
        """
        response = self.send_request(url, domain, REQUEST_METHOD['PUT'], header, *args, **kwargs)
        resp, log_content = CommonUtils.format_response_for_log(response)

        logger().debug(f"你的出参是：{log_content}")
        allure.attach(log_content, name='响应内容', attachment_type=allure.attachment_type.JSON)
        return resp

    def send_request(self, url, domain, request_type=REQUEST_METHOD['GET'], header=None, *args, **kwargs):
        full_url = self._full_url(domain, url)
        print('\n')
        logger().debug(f"请求地址为: {full_url}")

        headers = copy.deepcopy(self.cached_headers)

        if header:
            headers.update(header)
        # 把X-Authenticated-Userid放进header
        # 统一环境
        if "X-Authorization" not in headers:
            try:
                if self.param == 'demo_service':
                    headers.update(gbl.global_authorization_dic)
            except Exception as e:
                logger().debug(f'出错了，请检查登录模块。错误信息为：{e}')

        #请求方法
        if request_type == REQUEST_METHOD['GET']:
            if kwargs:
                resp = requests.get(url=full_url, params=kwargs['data'], headers=headers)
            else:
                resp = requests.get(url=full_url, headers=headers)
        elif request_type == REQUEST_METHOD['POST']:
            try:
                if kwargs:  # 字典非空，走下面逻辑
                    arg_data = kwargs['data']
                    try:
                        data = json.dumps(arg_data)  # 将str类型的数据转换为dict类型
                    except:
                        return Exception('入参格式错误')
                    resp = requests.post(full_url, headers=headers, data=data)
                else:  # 纯url请求
                    logger().debug('纯url请求')
                    resp = requests.post(url=full_url, headers=headers)
            except Exception as e:
                resp = None
                logger().debug(f'出错了，错误信息为：{e}')
        elif request_type == REQUEST_METHOD['DELETE']:
            logger().debug(full_url)
            resp = requests.delete(full_url, headers=headers)
        elif request_type == REQUEST_METHOD['PUT']:
            logger().debug(full_url)
            data = json.dumps(kwargs['data'])
            resp = requests.put(full_url, headers=headers, data=data)
        else:
            raise Exception('Request type must be one of [GET, POST]')
        #  增加自动化报告中的参数信息
        allure.attach(json.dumps(url, ensure_ascii=False, indent=4), name='请求地址',
                      attachment_type=allure.attachment_type.JSON)
        allure.attach(json.dumps(headers, ensure_ascii=False, indent=4), name='请求头',
                      attachment_type=allure.attachment_type.JSON)
        allure.attach(json.dumps(kwargs, ensure_ascii=False, indent=4, default=None), name='请求参数',
                      attachment_type=allure.attachment_type.JSON)
        return resp,headers

    def send_payload(param:dict):
        data = ''
        for key in sorted(param.keys()):
            data += key + '=' + str(param[key]) + '&'
        if len(data) > 0:
            data = data[0:-1]
        #logger().debug(f"转换str: {data}")
        #logger().debug(f"你看看啥格式行不行: {data}")
        return data